#ifndef CALCULATOR_H
#define	CALCULATOR_H

#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <sstream>
#include <cmath>
#include <algorithm>

class Calculator {
public:
    Calculator();
    Calculator(std::string input);
    
    void setInput(std::string input);

    double calculate();
private:
    struct Token {
        Token(std::string value, std::string type){this->value = value; this->type = type;}
        std::string value;
        std::string type;
    };

    std::string input;
    std::vector<Token> tokens;
    std::map<std::string, int> op;
    std::queue<Token> rpn;

    void init();
    void tokenize();
    void shuntingYard();
    double evaluate();
    bool unary(std::string op);
    int associative(Token op);
    int comparePrecedence(Token a, Token b);

    double factorial(double a);

    double min(std::deque<double> d);
    double max(std::deque<double> d);
    double log(std::deque<double> d);
    double root(std::deque<double> d);
    double sin(std::deque<double> d);
    double cos(std::deque<double> d);
    double tan(std::deque<double> d);
    double cot(std::deque<double> d);
    double sinh(std::deque<double> d);
    double cosh(std::deque<double> d);
    double tanh(std::deque<double> d);
    double coth(std::deque<double> d);
};

#endif	/* CALCULATOR_H */